package com.mxpio.erp.plan.controller;

import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.order.service.OrderLineService;
import com.mxpio.erp.common.order.service.OrderService;
import com.mxpio.erp.common.plan.entity.SalePrediction;
import com.mxpio.erp.common.plan.entity.SalePredictionLine;
import com.mxpio.erp.common.plan.service.SalePredictionLineService;
import com.mxpio.erp.common.plan.service.SalePredictionService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.policy.CrudContext;
import com.mxpioframework.jpa.policy.impl.SmartCrudPolicyAdapter;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.List;

@Slf4j
@Tag(name = "SalePredictionController", description = "销售预测接口")
@RestController
@RequestMapping("/erp/plan/sp/")
public class SalePredictionController {

	@Autowired
	private SalePredictionService salePredictionService;
	@Autowired
	private SalePredictionLineService salePredictionLineService;

	@Autowired
	private OrderService orderService;

	@Autowired
	private OrderLineService orderLineService;

	@GetMapping("list")
	@Operation(summary = "销售预测列表", description = "获取销售预测列表（无分页）", method = "GET")
	public Result<List<SalePrediction>> list(@Parameter(description = "查询参数") Criteria criteria)
			throws UnsupportedEncodingException {
		List<SalePrediction> salePrediction = salePredictionService.list(SalePrediction.class, criteria);
		return Result.OK(salePrediction);
	}
	
	@GetMapping("page")
	@Operation(summary = "销售预测列表", description = "获取销售预测列表（分页）", method = "GET")
	public Result<Page<SalePrediction>> page(@Parameter(description = "查询参数") Criteria criteria,
			@Parameter(description = "每页条数") Integer pageSize, @Parameter(description = "页号") Integer pageNo)
			throws UnsupportedEncodingException {
		Pageable page = PageRequest.of(pageNo - 1, pageSize);
		Page<SalePrediction> salePrediction = salePredictionService.listPage(SalePrediction.class, page, criteria);
		return Result.OK(salePrediction);
	}

	@GetMapping("list/{id}")
	@Operation(summary = "根据id获取销售预测", description = "根据id获取销售预测", method = "GET")
	public Result<SalePrediction> getById(
			@Parameter(description = "ID") @PathVariable(name = "id", required = true) String id) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, id);
		return Result.OK(salePrediction);
	}

	@RequestMapping("save")
	@Operation(summary = "保存销售预测", description = "保存销售预测")
	@Transactional(readOnly = false)
	public Result<SalePrediction> save(@RequestBody SalePrediction salePrediction) {
		salePredictionService.save(salePrediction,new SmartCrudPolicyAdapter(){
			@Override
			public boolean beforeInsert(CrudContext context) {
				Object o = context.getEntity();
				if(o instanceof SalePredictionLine){
					SalePrediction dbSalePrediction = context.getParent();
					((SalePredictionLine) o).setBizNo(dbSalePrediction.getBizNo());
				}
				return true;
			}
		});
		return Result.OK(salePrediction);
	}

	@DeleteMapping("remove/{ids}")
	@Operation(summary = "根据ids删除销售预测", description = "删除销售预测", method = "DELETE")
	@Transactional(readOnly = false)
	public Result<SalePrediction> remove(
			@Parameter(description = "id，多个单号用英文逗号分隔") @PathVariable(name = "ids", required = true) String ids) {
		String[] id = ids.split(",");
		for (String key : id) {
			Criteria c = Criteria.create().addCriterion("bizNo", Operator.EQ, key);
			salePredictionLineService.removeBatch(SalePredictionLine.class, c);
			salePredictionService.delete(SalePrediction.class, key);
		}
		return Result.OK();
	}
	
	@PutMapping("submit/{id}")
    @Operation(summary = "提交销售预测", description = "提交销售预测", method = "PUT")
    public Result<SalePrediction> submit(@Parameter(description = "ID") @PathVariable(name = "id", required = true) String id) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, id);
        if (salePrediction.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode())) {
            return salePredictionService.updateBpmnStatus(salePrediction, OrderStatusEnums.BpmnStatus.AUDITING);
        } else {
            return Result.error("非开立状态不可提交");
        }
    }
	
	@PutMapping("audit/{id}")
    @Operation(summary = "审核销售预测", description = "审核销售预测", method = "PUT")
    public Result<SalePrediction> audit(@Parameter(description = "ID") @PathVariable(name = "id", required = true) String id) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, id);
        if (salePrediction.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())) {
            return salePredictionService.updateBpmnStatus(salePrediction,OrderStatusEnums.BpmnStatus.AUDITED);
        } else {
            return Result.error("非审核中状态不可审核");
        }
    }

    @PutMapping("abandon/{id}")
    @Operation(summary = "弃审销售预测", description = "弃审销售预测", method = "PUT")
    public Result<SalePrediction> abandon(@Parameter(description = "ID") @PathVariable(name = "id", required = true) String id) {
    	SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, id);
        if (salePrediction.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())
				|| salePrediction.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())) {
            return salePredictionService.updateBpmnStatus(salePrediction, OrderStatusEnums.BpmnStatus.CREATE);
        } else {
            return Result.error("非审核中、已审核状态不可审核");
        }
    }


	@PutMapping("close/{id}")
	@Operation(summary = "关闭销售预测", description = "关闭销售预测", method = "PUT")
	public Result<SalePrediction> close(@Parameter(description = "ID") @PathVariable(name = "id", required = true) String id) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, id);
		if (salePrediction.getBpmnStatus().equals(OrderStatusEnums.CloseStatus.OPEN.getStatusCode())) {
			return salePredictionService.updateCloseStatus(salePrediction, OrderStatusEnums.CloseStatus.CLOSED);
		} else {
			return Result.error("已关闭状态不可重复关闭");
		}
	}

	@PutMapping("open/{id}")
	@Operation(summary = "打开销售预测", description = "打开销售预测", method = "PUT")
	public Result<SalePrediction> open(@Parameter(description = "ID") @PathVariable(name = "id", required = true) String id) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, id);
		if (salePrediction.getBpmnStatus().equals(OrderStatusEnums.CloseStatus.CLOSED.getStatusCode())) {
			return salePredictionService.updateCloseStatus(salePrediction, OrderStatusEnums.CloseStatus.OPEN);
		} else {
			return Result.error("已打开状态不可重复打开");
		}
	}
	/*@RequestMapping("execute/receive/{bizNo}")
	@Operation(summary = "", description = "收料")
	public Result<Object> receiveExec(@PathVariable(name = "bizNo", required = true) String bizNo,
									  @RequestBody OrderExcuteVo orderExcuteVo) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, bizNo);
		OrderContext context = orderService.execute(salePrediction, new DefaultODRecPolicy(orderExcuteVo.getLines(),orderLineService));
		if(CollectionUtils.isEmpty(context.getErrors())) {
			return Result.OK();
		}else {
			return Result.error(context.getErrors().get(0));
		}
	}

	@RequestMapping("execute/reject/{bizNo}")
	@Operation(summary = "退货", description = "退料")
	public Result<Object> rejectExec(@PathVariable(name = "bizNo", required = true) String bizNo,
									 @RequestBody OrderExcuteVo orderExcuteVo) {
		SalePrediction salePrediction = salePredictionService.getById(SalePrediction.class, bizNo);
		OrderContext context = orderService.execute(salePrediction, new DefaultODRejectPolicy(orderExcuteVo.getLines(),orderLineService));
		if(CollectionUtils.isEmpty(context.getErrors())) {
			return Result.OK();
		}else {
			return Result.error(context.getErrors().get(0));
		}
	}*/
}
